home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: hp26.trm%v 3.50 1993/07/09 05:35:24 woo Exp $
- */
-
- /* GNUPLOT - HP26.trm */
- /*
- * Copyright (C) 1990
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the modified code. Modifications are to be distributed
- * as patches to released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- * This file is included by ../term.c.
- *
- * This terminal driver supports:
- * HP2623A
- *
- * AUTHORS
- * luecken@udel.edu (Bruce Lueckenhoff)
- * hplvlch!ch (Chuck Heller)
- *
- * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
- *
- */
-
-
- #define HP26_XMAX 512
- #define HP26_YMAX 390
-
- #define HP26_XLAST (HP26_XMAX - 1)
- #define HP26_YLAST (HP26_XMAX - 1)
-
- /* Use a size 1 character, or a 7 x 10 grid. */
- #define HP26_VCHAR 10
- #define HP26_HCHAR 7
- #define HP26_VTIC 5
- #define HP26_HTIC 5
-
- /* include the stream compaction routines */
- #include "compact.c"
-
- typedef struct _HP26_Buffer_Node{
- int index;
- int size;
- int next;
- int linetype;
- int *x;
- int *y;
- TBOOLEAN *isa_move;
- } HP26_Buffer_Node;
-
- /* constructor method */
- HP26_Buffer_Node *BN_create(index, size, linetype)
- int index, size, linetype;
- {
- HP26_Buffer_Node *the_node;
- the_node = (HP26_Buffer_Node *) malloc(sizeof(HP26_Buffer_Node));
- the_node->index = index;
- the_node->linetype = linetype;
- the_node->size = size;
- the_node->next = 0;
- the_node->x = (int *) calloc(the_node->size, sizeof(int));
- the_node->y = (int *) calloc(the_node->size, sizeof(int));
- the_node->isa_move = (TBOOLEAN *)calloc(the_node->size,sizeof(TBOOLEAN));
- if (the_node->x == NULL
- ||the_node->y == NULL
- ||the_node->isa_move == NULL)
- return (NULL);
- else
- return(the_node);
- }
-
- /* destructor method */
- void BN_delete(the_node)
- HP26_Buffer_Node *the_node;
- {
- free(the_node->x);
- free(the_node->y);
- free(the_node->isa_move);
- free(the_node);
- }
-
- /* 2 for border and axes + 9 for plots + 1 for dots */
- #define HP26_gnu_map_size 12
- HP26_Buffer_Node *HP26_gnu_map[HP26_gnu_map_size];
- HP26_Buffer_Node *HP26_buff;
- int HP26_pen_x;
- int HP26_pen_y;
- int HP26_angle;
- int HP26_cursor_x;
- int HP26_cursor_y;
- TBOOLEAN HP26_in_text;
- int HP26_linetype_current;
- int HP26_reduction_int;
- int HP26_reduction_slope;
- int HP26_overflows;
- int HP26_nop_move;
- int HP26_nop_vect;
- int HP26_nop_line;
-
- /* linetype stuff */
- #define SOLID 1
- #define USER 2
- #define LINE3 3
- #define LINE4 4
- #define LINE5 5
- #define LINE6 6
- #define DOTS 7
- #define LINE8 8
- #define LINE9 9
- #define LINE10 10
- #define POINT 11
-
-
-
- #define swap(a, b) a ^= b; b ^= a; a ^= b;
-
- char HP26_bin_short_table[32]={
- '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',
- ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/'};
- /* encodes an integer (assumed to be in range) into
- binary short incremental format (j)*/
- #define short_encode(n) (HP26_bin_short_table[n+16])
-
- /* tells whether a given delta_x,delta_y pair can be expressed in
- binary short incremental format */
- #define qualified(dx,dy) ((dx>-17)&&(dy>-17)&&(dx<16)&&(dy<16))
-
-
- char HP26_bin_table[32]={
- ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',
- '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?'};
- /* returns the high byte of integer n in binary absolute format (i) */
- #define bin_encode_hi(n) (HP26_bin_table[n>>5])
- /* returns the low byte of integer n in binary absolute format (i) */
- #define bin_encode_lo(n) (HP26_bin_table[n & 31])
-
-
-
- /* the guts of the program
- -- first checks if any work need be done and, failing that, returns
- immediately
- -- tries to compress the vector stream
- -- goes through the buffer, using binary short incremental (2 bytes/point)
- as much as possible, even if must output two pairs to express one vector
- (it's no more expensive, and will hopefully damp any excessive switching
- back and forth between the two formats)
- if can't use binary short incremental, use binary
- absolute(4 bytes/point)
- -- finally, resets the HP26_next pointer to zero */
- HP26_flush(the_buff)
- HP26_Buffer_Node *the_buff;
- {
- int i, delta_x, delta_y, half_dx, half_dy;
- int *buff_x, *buff_y;
- TBOOLEAN *isa_move;
- TBOOLEAN bin_short;
-
- if (the_buff->next == 0)
- return (FALSE);
- /* init pointers for easy access */
- buff_x = the_buff->x;
- buff_y = the_buff->y;
- isa_move = the_buff->isa_move;
- if (HP26_in_text){
- fputs("\033*dT", outfile);
- HP26_in_text = FALSE;
- }
- if (HP26_linetype_current != the_buff->linetype
- && (the_buff->next > 1 || !isa_move[0])){
- fprintf(outfile,"\033*m%dB",the_buff->linetype);
- HP26_linetype_current = the_buff->linetype;
- }
- /* try to compress the stream */
- if (the_buff->next>30 && the_buff->linetype != POINT){
- /* HP26_reduction_int += compact_int(buff_x,buff_y,isa_move, &(the_buff->next)); */
- HP26_reduction_slope += compact_slope(buff_x,buff_y,isa_move, &(the_buff->next),0.1);
- }
-
- /* start escape sequence */
- fputs("\033*p",outfile);
- /* initialize the state: binary short incremental or binary absolute */
- delta_x = buff_x[0] - HP26_pen_x;
- delta_y = buff_y[0] - HP26_pen_y;
- if (qualified(delta_x, delta_y)){
- fputc('j', outfile);
- bin_short = TRUE;
- }else{
- fputc('i', outfile);
- bin_short = FALSE;
- }
- /* now work through the list */
- for (i=0;i<the_buff->next;i++){
- if (i>0){
- delta_x = buff_x[i] - buff_x[i-1];
- delta_y = buff_y[i] - buff_y[i-1];
- }
- if ((delta_x==0)&&(delta_y==0)){
- if (i>0 && !isa_move[i-1] && !isa_move[i]){
- /* allow null vectors only when drawing dots */
- HP26_nop_vect++;
- continue;
- }else if (isa_move[i]){
- /* a null move */
- HP26_nop_move++;
- continue;
- }
- }else if (i > 0
- && i+1 <the_buff->next
- && isa_move[i]
- && isa_move[i+1]){
- /* consecutive moves are condensed into one */
- HP26_nop_move++;
- continue;
- }else if (!qualified(delta_x, delta_y)
- && i > 0
- && i + 2 < the_buff->next
- && isa_move[i]
- && !isa_move[i+1]
- && isa_move[i+2]
- &&qualified(buff_x[i+1]-buff_x[i-1],buff_y[i+1]-buff_y[i-1])){
- swap(buff_x[i], buff_x[i+1]);
- swap(buff_y[i], buff_y[i+1]);
- /* set up new delta_x & delta_y */
- delta_x = buff_x[i] - buff_x[i-1];
- delta_y = buff_y[i] - buff_y[i-1];
- }
- if (qualified(delta_x,delta_y)){
- if (!bin_short){
- fputc ('j',outfile);
- bin_short = TRUE;
- }
- if (isa_move[i])
- fputc ('a',outfile);
- fputc(short_encode(delta_x), outfile);
- fputc(short_encode(delta_y), outfile);
- }else{
- half_dx = (delta_x + (delta_x>0 ? 1 : -1))/2;
- half_dy = (delta_y + (delta_y>0 ? 1 : -1))/2;
- if (bin_short && qualified(half_dx,half_dy)){
- if (isa_move[i])
- fputc('a',outfile);
- fputc(short_encode(half_dx), outfile);
- fputc(short_encode(half_dy), outfile);
- if (isa_move[i])
- fputc('a',outfile);
- fputc(short_encode(delta_x - half_dx), outfile);
- fputc(short_encode(delta_y - half_dy), outfile);
- }else{
- if (bin_short){
- bin_short = FALSE;
- fputc('i',outfile);
- }
- if (isa_move[i])
- fputc('a',outfile);
- fputc(bin_encode_hi(buff_x[i]), outfile);
- fputc(bin_encode_lo(buff_x[i]), outfile);
- fputc(bin_encode_hi(buff_y[i]), outfile);
- fputc(bin_encode_lo(buff_y[i]), outfile);
- }
- }
- } /* end for.. */
- /* the term doesn't seem to mind leaving this out */
- /* finish the escape sequence */
- fputc ('Z',outfile);
- /* set these for next time */
- HP26_pen_x = buff_x[the_buff->next - 1];
- HP26_pen_y = buff_y[the_buff->next - 1];
- the_buff->next = 0;
- return(TRUE);
- }
-
- HP26_handle_overflow()
- {
- HP26_Buffer_Node *bigger, *old;
- int x, y;
- x = (HP26_buff->x)[HP26_buff->next - 1];
- y = (HP26_buff->y)[HP26_buff->next - 1];
- HP26_flush(HP26_buff);
- bigger = BN_create(HP26_buff->index, HP26_buff->size * 2,
- HP26_buff->linetype);
- if (bigger != NULL){
- old = HP26_buff;
- HP26_gnu_map[bigger->index] = bigger;
- /* special case since DOTS entry is shared 3 ways */
- if(bigger->index == 0){
- HP26_gnu_map[1] = bigger;
- HP26_gnu_map[3] = bigger;
- }
- HP26_buff = bigger;
- BN_delete(old);
- }
- (HP26_buff->x)[0] = x;
- (HP26_buff->y)[0] = y;
- (HP26_buff->isa_move)[0] = TRUE;
- HP26_buff->next = 1;
- HP26_overflows++;
- }
-
- /* checks for NOP, overcapacity condition, and then adds vector to the list */
- HP26_vector(x,y)
- int x,y;
- {
- if (HP26_buff->next > 2
- && x == (HP26_buff->x)[HP26_buff->next-1]
- && y == (HP26_buff->y)[HP26_buff->next-1]
- && !(HP26_buff->isa_move)[HP26_buff->next-1] ){
- HP26_nop_vect++;
- return(FALSE);
- }
- if (HP26_buff->next == HP26_buff->size)
- HP26_handle_overflow();
- /* otherwise add to the list */
- (HP26_buff->x)[HP26_buff->next] = x;
- (HP26_buff->y)[HP26_buff->next] = y;
- (HP26_buff->isa_move)[HP26_buff->next] = FALSE;
- HP26_buff->next++;
- }
-
- /* checks for NOP, checks for overcapacity, puts self on list */
- HP26_move(x,y)
- int x,y;
- {
- if (HP26_buff->next > 0){
- if (((HP26_buff->x)[HP26_buff->next - 1] == x)
- &&((HP26_buff->y)[HP26_buff->next - 1] == y)){
- /* null moves are NOP's */
- HP26_nop_move++;
- return (FALSE);
- }else if ((HP26_buff->isa_move)[HP26_buff->next-1]){
- /* consecutive moves are NOP's */
- (HP26_buff->x)[HP26_buff->next-1] = x;
- (HP26_buff->y)[HP26_buff->next-1] = y;
- HP26_nop_move++;
- return (TRUE);
- }
- }
- if (HP26_buff->next == HP26_buff->size)
- HP26_handle_overflow();
- (HP26_buff->x)[HP26_buff->next] = x;
- (HP26_buff->y)[HP26_buff->next] = y;
- (HP26_buff->isa_move)[HP26_buff->next] = TRUE;
- HP26_buff->next++;
- return (TRUE);
- }
-
- HP26_init()
- {
- HP26_gnu_map[-2 + 2] = BN_create( 0, 2048, DOTS); /* border */
- HP26_gnu_map[-1 + 2] = HP26_gnu_map[-2 + 2]; /* axes */
- HP26_gnu_map[ 0 + 2] = BN_create( 2, 3072, SOLID); /* plot 0 */
- HP26_gnu_map[ 1 + 2] = HP26_gnu_map[-2 + 2]; /* plot 1 */
- HP26_gnu_map[ 2 + 2] = BN_create( 4, 1024, LINE5); /* plot 2 */
- HP26_gnu_map[ 3 + 2] = BN_create( 5, 256, LINE6); /* plot 3 */
- HP26_gnu_map[ 4 + 2] = BN_create( 6, 256, LINE8); /* plot 4 */
- HP26_gnu_map[ 5 + 2] = BN_create( 7, 128, LINE9); /* plot 5 */
- HP26_gnu_map[ 6 + 2] = BN_create( 8, 128, LINE10); /* plot 6 */
- HP26_gnu_map[ 7 + 2] = BN_create( 9, 64, LINE6); /* plot 7 */
- HP26_gnu_map[ 8 + 2] = BN_create(10, 64, LINE4); /* plot 8 */
- HP26_gnu_map[ 9 + 2] = BN_create(11, 512, POINT); /* point plot */
- HP26_buff = HP26_gnu_map[10]; /* set to an unlikely linetype */
- HP26_linetype_current = 0; /* set to force a linetype change */
- HP26_angle = 1; /* left to right, default */
- fputs("\033*mp1m2a2Q",outfile);
- /* 1 2 3 4
- 1. make text upright
- 2. select text size 1
- 3. make SET the default drawing op
- 4. left justify text */
- fflush (outfile);
- }
-
-
- HP26_graphics()
- {
- fputs("\033*daflsC", outfile);
- /* 12345
- 1. clear graphics display
- 2. shut off the alphanumeric display
- 3. graphics cursor off
- 4. into graphics text mode
- 5. enable graphics display */
- /* set the pen & cursor positions to force an initial absolute move */
- HP26_pen_x = HP26_pen_y = -200;
- HP26_cursor_x = HP26_cursor_y = 800;
- HP26_in_text = TRUE;
- /* initialize statistics */
- HP26_reduction_int = 0;
- HP26_reduction_slope = 0;
- HP26_nop_move = 0;
- HP26_nop_vect = 0;
- HP26_nop_line = 0;
- HP26_overflows = 0;
- }
-
-
- HP26_text()
- {
- int i, j, curr;
-
- /* always flush the current line first */
- for (i=0;i<HP26_gnu_map_size;i++)
- if ((HP26_gnu_map[i])->linetype == HP26_linetype_current)
- HP26_flush(HP26_gnu_map[i]);
- /* now flush the rest of the lines */
- for (i=0;i<HP26_gnu_map_size;i++){
- HP26_flush(HP26_gnu_map[i]);
- curr = HP26_gnu_map[i] -> linetype;
- for (j=0;j<HP26_gnu_map_size;j++)
- if ((HP26_gnu_map[j])->linetype == curr)
- HP26_flush(HP26_gnu_map[j]);
- }
- fputs("\033*deT",outfile);
- /* 12
- 1. turn on the alphanumeric display
- 2. back to text mode */
- fflush(outfile);
- /* informational: tells how many points compressed, how
- many NOP's of each type, and how many times a buffer
- overflowed during this plot */
- /*
- if(HP26_reduction_int
- + HP26_reduction_slope
- + HP26_nop_move
- + HP26_nop_vect
- + HP26_overflows
- + HP26_nop_line > 0){
- if (HP26_reduction_int>0)
- printf("%d int-compress",HP26_reduction_int);
- if (HP26_reduction_slope>0)
- printf("%d slope-compress",HP26_reduction_slope);
- if (HP26_nop_move>0)
- printf(" %d nop_move",HP26_nop_move);
- if (HP26_nop_vect>0)
- printf(" %d nop_vect",HP26_nop_vect);
- if (HP26_nop_line>0)
- printf(" %d nop_line",HP26_nop_line);
- if (HP26_overflows>0)
- printf(" %d buffer overflows",HP26_overflows);
- printf("\n");
- }
- */
- }
-
- HP26_reset()
- {
- int i;
- for (i=0;i<HP26_gnu_map_size;i++)
- BN_delete(HP26_gnu_map[i]);
- }
-
- HP26_text_angle (ang)
- int ang;
- {
- HP26_angle = ang + 1;
- fprintf(outfile,"\033*m%dN",HP26_angle);
- return(TRUE);
- }
-
-
- HP26_put_text(x, y,str)
- int x, y;
- char *str;
- {
- char abs_str[10],rel_str[10];
-
- if (!strlen(str))
- return(FALSE);
- else{
- fputs("\033*d", outfile);
- if (!HP26_in_text){
- fputc('s', outfile);
- HP26_in_text = TRUE;
- }
- sprintf(rel_str,"%d,%dP",x - HP26_cursor_x, y - HP26_cursor_y);
- sprintf(abs_str,"%d,%dO", x, y);
- if (strlen(rel_str) < strlen(abs_str))
- fputs(rel_str, outfile);
- else
- fputs(abs_str, outfile);
- fputs(str, outfile);
- HP26_pen_x = HP26_cursor_x = x;
- HP26_pen_y = HP26_cursor_y = y;
- }
- /*
- tmp = &(HP26_all_buffers[HP26_linetype_current]);
- tmp->x[tmp->next] = x;
- tmp->y[tmp->next] = y;
- tmp->isa_move[tmp->next] = TRUE;
- tmp->next++;
- HP26_flush(tmp);
- fprintf(outfile,"\033*l%s\r",str);
- */
- return(TRUE);
- }
-
-
- /* checks for NOP, sets HP26_buff to point to the right buffer */
- HP26_linetype(linetype)
- int linetype;
- {
- if (linetype > 8)
- linetype %= 9;
- linetype += 2;
- if (HP26_gnu_map[linetype] == HP26_buff){
- HP26_nop_line++;
- return (FALSE); /* gnuplot just sent us another NOP */
- }
- HP26_buff = HP26_gnu_map[linetype];
- return (TRUE);
- }
-
-
-
- /* switches to a solid linetype and calls do_point, then switches back */
- HP26_line_and_point(x,y,number)
- int x,y,number;
- {
- int line_save,not_solid;
-
- not_solid = (HP26_buff->linetype != SOLID);
- if (not_solid){
- line_save = HP26_buff->linetype;
- HP26_linetype (0); /*switch to a solid line*/
- }
- HP26_do_point(x, y, number);
- if (not_solid)
- HP26_linetype(line_save);
- return (TRUE);
- }
-
-
- /* provides 9 point types so they stay in sync with the linetypes
- puts simpler point types first on the assumption they are more
- frequently used */
- HP26_do_point (x, y,number)
- int x, y,number;
- {
- int htic,vtic;
- HP26_Buffer_Node *tmp;
-
- vtic = HP26_VTIC/2;
- htic = HP26_HTIC/2;
- if (number<0){
- /* do a dot -- special case */
- tmp = HP26_buff;
- HP26_buff = HP26_gnu_map[11]; /* point plot */
- HP26_vector(x, y);
- HP26_buff = tmp;
- return(TRUE);
- }
- switch (number % 9){
- case 0:
- /* do triangle */
- HP26_move(x-htic, y-vtic);
- HP26_vector(x, y+vtic);
- HP26_vector(x+htic, y-vtic);
- HP26_vector(x-htic, y-vtic);
- break;
- case 1:
- /* do nambla */
- HP26_move(x-htic, y+vtic);
- HP26_vector(x, y-vtic);
- HP26_vector(x+htic, y+vtic);
- HP26_vector(x-htic, y+vtic);
- break;
- case 2:
- /* do left triangle */
- HP26_move(x-htic, y);
- HP26_vector(x+htic, y+vtic);
- HP26_vector(x+htic, y-vtic);
- HP26_vector(x-htic, y);
- break;
- case 3:
- /* do right triangle */
- HP26_move(x+htic, y);
- HP26_vector(x-htic, y+vtic);
- HP26_vector(x-htic, y-vtic);
- HP26_vector(x+htic, y);
- break;
- case 4:
- /* do box */
- HP26_move(x-htic, y-vtic);
- HP26_vector(x-htic, y+vtic);
- HP26_vector(x+htic, y+vtic);
- HP26_vector(x+htic, y-vtic);
- HP26_vector(x-htic, y-vtic);
- break;
- case 5:
- /* do plus */
- HP26_move(x, y+vtic);
- HP26_vector(x, y-vtic);
- HP26_move(x-htic, y);
- HP26_vector(x+htic, y);
- break;
- case 6:
- /* do X */
- HP26_move(x+htic, y+vtic);
- HP26_vector(x-htic, y-vtic);
- HP26_move(x-htic, y+vtic);
- HP26_vector(x+htic, y-vtic);
- break;
- default:
- /* do diamond */
- HP26_move(x, y-vtic);
- HP26_vector(x-htic, y);
- HP26_vector(x, y+vtic);
- HP26_vector(x+htic, y);
- HP26_vector(x, y-vtic);
- break;
- }
- return(TRUE);
- }
-